/*
 *      info.h
 *      
 *      Copyright 2009 AL <skylark@skylark-desktop>
 */

#ifndef INFO_H
#define INFO_H

#include <iostream>
#include "infoid.h"
#include "entityid.h"
#include "sensorlevels.h"
#include "serialization.h"

/* forward declaration */
//class Object;

typedef enum{itBool, itInt, itInfoId, itFloat, itString/*, itEntityList, itObjectList*/} EInfoType;
typedef enum{isReal=0, isSense=1, isReasoning=2, isMemory=3} EInfoSource;
#define I_SOURCE_TYPES 4 /* amount of EInfoSource-entries */

class Info {
    public:
    /* set, construct, destruct */
    Info(bool _b);
    Info(int _i);
    Info(float _f);
    ~Info();
    void set(bool _b);
    void set(int _i);
    void set(float _f);
	//void setSensorMetadata(
    /* use there direct accessors if you are sure of data type */ 
    bool& b();
    int& i();
    float& f();
    EInfoType getType();

	/* stream functions */
    void toStream(std::ostream& os, unsigned int indent=0, ESerializationType sertype=stFull) const;
	friend std::ostream& operator<<(std::ostream& os, const Info& info);

    /* ----------------- DATA ------------------ */
	protected:
	EInfoType type;
	union {
		bool boolValue;
		int intValue;
		
		float floatValue;
		std::string *stringValue;
		//Object *objectValue;
		// entityList
	};
	/* ---------------- METADATA --------------- */
    public:
	EInfoSource source;
    // SensorLevels sensability;
	//Object *sourceObject; /* if source=communication */
	//float valuePrecision; /* 0=exact..1=no data; evaluated relative error margin */	
    //float updateTime; /* time the data is updated */
    // bliiblaabluu...

};

#endif /* INFO_H */










#define OBJECTPROPERTY_HH /* TO REMOVE SECTION BELOW */


#ifndef OBJECTPROPERTY_HH
#define OBJECTPROPERTY_HH

/* class ObjectProperty is assignable. Copied (destination) element maintains
 * same references to external variables as the original does.
 * copy constuctor and operator=() are overloaded.
 *
 * to add a new property:
 *      - add it here (#define and typedef lines)
 *      - add to ObjectProperty::thresholdLevels()
 *      - add property to Object(or descendent) constructor
 *	    - visualize in WorldGraphics::drawObject() & WorldGraphics::drawSignal()
 */

#include "coord.hh"
#include "signallevels.hh"

/* ---------------------- OBJECT PROPERTIES ------------------------------ */

typedef enum{
	OBJPROP_NONE       = 0,
	OBJPROP_POSITION   = 1,
    OBJPROP_VELOCITY   = 2,
    OBJPROP_RADIUS     = 3,
	OBJPROP_CLASSID    = 4,
	OBJPROP_INSTANCEID = 5,

    OBJPROP_ORG_ALIVE       = 6,
    OBJPROP_ORG_SPECIESID   = 7,
    OBJPROP_ORG_EDIBLE_MASS = 8,

	OBJPROP_CR_DIRECTION  =  9,
    OBJPROP_CR_IS_MALE    = 10,
    OBJPROP_CR_TASK       = 11,
    OBJPROP_CR_ARMOR_THCK = 12,
    OBJPROP_CR_WEAPON_LEN = 13

} EObjectPropertyId;

/* ------------------- CREATURE TASK NUMBERS ------------------------------- */

#define CR_TASK_IDLE     0
#define CR_TASK_MOVE     1
#define CR_TASK_INGEST   2
#define CR_TASK_ATTACK   3
#define CR_TASK_PULL     4
#define CR_TASK_MATE     5
#define CR_TASK_DELIVERY 6
#define CR_TASK_RELOAD   7
#define CR_TASK_DEAD     8

/* ------------------ OBJECT PROPERTY SIGHT THRESHOLDS ---------------------- */

#define OBJPROP_SIGHT_NONE            1.0f
#define OBJPROP_SIGHT_POSITION        1.0f
#define OBJPROP_SIGHT_VELOCITY        1.0f
#define OBJPROP_SIGHT_RADIUS          1.4f
#define OBJPROP_SIGHT_CLASSID         1.8f
#define OBJPROP_SIGHT_INSTANCEID      3.5f
#define OBJPROP_SIGHT_ORG_ALIVE       2.4f
#define OBJPROP_SIGHT_ORG_SPECIESID   2.1f
#define OBJPROP_SIGHT_ORG_EDIBLE_MASS 2.4f
#define OBJPROP_SIGHT_CR_DIRECTION    2.0f
#define OBJPROP_SIGHT_CR_IS_MALE      2.7f
#define OBJPROP_SIGHT_CR_TASK         2.8f
#define OBJPROP_SIGHT_CR_ARMOR_THCK   3.1f
#define OBJPROP_SIGHT_CR_WEAPON_LEN   2.4f

/* ------------------ OBJECT PROPERTY HEAR THRESHOLDS ----------------------- */

#define OBJPROP_HEAR_NONE              1.0f
#define OBJPROP_HEAR_POSITION          1.8f
#define OBJPROP_HEAR_VELOCITY          2.1f
#define OBJPROP_HEAR_RADIUS           12.0f
#define OBJPROP_HEAR_CLASSID           3.0f
#define OBJPROP_HEAR_INSTANCEID        4.5f
#define OBJPROP_HEAR_ORG_ALIVE         3.5f
#define OBJPROP_HEAR_ORG_SPECIESID     3.5f
#define OBJPROP_HEAR_ORG_EDIBLE_MASS   4.5f
#define OBJPROP_HEAR_CR_DIRECTION     20.0f
#define OBJPROP_HEAR_CR_IS_MALE        4.0f
#define OBJPROP_HEAR_CR_TASK           4.0f
#define OBJPROP_HEAR_CR_ARMOR_THCK    20.0f
#define OBJPROP_HEAR_CR_WEAPON_LEN    50.0f

/* ------------------ OBJECT PROPERTY TOUCH THRESHOLDS ----------------------- */

#define OBJPROP_TOUCH_NONE              1.0f
#define OBJPROP_TOUCH_POSITION          1.0f
#define OBJPROP_TOUCH_VELOCITY          1.5f
#define OBJPROP_TOUCH_RADIUS            2.0f
#define OBJPROP_TOUCH_CLASSID           4.0f
#define OBJPROP_TOUCH_INSTANCEID       12.0f
#define OBJPROP_TOUCH_ORG_ALIVE        12.0f
#define OBJPROP_TOUCH_ORG_SPECIESID     6.0f
#define OBJPROP_TOUCH_ORG_EDIBLE_MASS   6.0f
#define OBJPROP_TOUCH_CR_DIRECTION      4.0f
#define OBJPROP_TOUCH_CR_IS_MALE        4.0f
#define OBJPROP_TOUCH_CR_TASK          12.0f
#define OBJPROP_TOUCH_CR_ARMOR_THCK     4.0f
#define OBJPROP_TOUCH_CR_WEAPON_LEN     3.5f

/* -------------------- OBJECT PROPERTY CLASS ------------------------------- */


typedef enum{opNotExist/*not existing property*/, opNoData/*no info avail*/, opFloat, opBool, opInt, opCoord, opFloatRef, opBoolRef, opIntRef, opCoordRef} EObjectPropertyType;

class ObjectProperty {
  public:
  /* constructors */
  ObjectProperty(EObjectPropertyId _id, float *_value);
  ObjectProperty(EObjectPropertyId _id, Coord *_value);
  ObjectProperty(EObjectPropertyId _id, bool *_value);
  ObjectProperty(EObjectPropertyId _id, unsigned int *_value);
  ObjectProperty(EObjectPropertyId _id, bool _value);
  ObjectProperty(EObjectPropertyId _id, unsigned int _value);

  /* assignment operator and copy-construction. references of ref-type values are maintained i.e. "swallow copy for them" */
  ObjectProperty(const ObjectProperty& o, bool swallow=true);
  ObjectProperty& operator=(const ObjectProperty& o);

  /* compare-operators */
  bool operator<(const ObjectProperty& o);
  bool operator==(const ObjectProperty& o);

  ~ObjectProperty();

  void copyFrom(const ObjectProperty& original); /* makes (source=original, destination=this) a non-pointer-copy of original */

  EObjectPropertyId id;
  EObjectPropertyType type;
  union {
    float floatVal;
	bool boolVal;
	unsigned int intVal;

	float *floatRef;
	bool *boolRef;
    unsigned int *intRef;
	Coord *coordRef;
    Coord *coordVal;
  } value;

  /* static functions */
  SignalLevels thresholdLevels() const;

  /* stream functions */
  void toStream(std::ostream& os, bool short_version=false) const;
  friend std::ostream& operator<<(std::ostream& os, const ObjectProperty& o);

};

#endif /* OBJECTPROPERTY_HH */
